/*
 * Copyright (c) 2009-2013 EvTech Project
 * All rights reserved.
 * 
 * This file is part of Game packet.
 *
 * Game packet is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or 
 * (at your option) any later version.
 *
 * Game packet is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Game packet.  If not, see <http://www.gnu.org/licenses/>.
 * 
 */
package fi.honkalampisaatio.game.selection;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.EventObject;
import java.util.Iterator;

import javax.swing.AbstractButton;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JPanel;

import fi.honkalampisaatio.game.game.LanguageResource;
import fi.honkalampisaatio.game.game.MediaResource;
import fi.honkalampisaatio.game.xml.GameSettings;
import fi.honkalampisaatio.game.xml.SettingsReader;
import fi.honkalampisaatio.game.xml.UserSetting;

public class GameSelection extends JPanel implements KeyListener {

	private static final long serialVersionUID = 2858305145638556531L;

	private SelectionListener listener = null;

	private static final String BACKBUTTON_IMAGE = "./settings/backbutton.gif";
	private String backButtonText;
	
	protected int iconHeight = 80;
	protected int iconWidth = 100;
	
	public GameSelection() {
		this.addKeyListener(this);
		refreshLanguage();
	}


	public void refreshLanguage()
	{
		LanguageResource dictionary = LanguageResource.getInstance();
		if(dictionary!=null)
			backButtonText = dictionary.get("CANCELBUTTON_TEXT");
		if(backButtonText==null || backButtonText.isEmpty())
			backButtonText = "Palaa";
	}
	
	public void setForeground(Color color)
	{
		super.setForeground(color);
		Component[] compList = this.getComponents();
		for(int i=0;i<compList.length;i++)
		{
			compList[i].setForeground(color);
		}
	}

	public void setFont(Font font)
	{
		super.setFont(font);
		Component[] compList = this.getComponents();
		System.out.println("Komponenttien määrä " + compList.length);
		for(int i=0;i<compList.length;i++)
		{
			float fontSize = 12;
			if(compList[i] instanceof JButton)
			{
				fontSize = ((JButton)compList[i]).getFont().getSize2D();
			}
			compList[i].setFont(font.deriveFont(fontSize));
		}
	}

	
	/**
	 * Generoidaan nappi, jolla parametrina saadussa tiedostossa
	 * määritelty peli saadaan käyntiin...
	 * @param gameSettings
	 */
	private Component generateSelectionButton(final GameSettings gameSetting) {
		JButton btn = null;
		ImageIcon btnIcon = createImageIcon(gameSetting.getMenuImage(), 
				gameSetting.getName());
		if(btnIcon!=null) {
			btn = new JButton(gameSetting.getName(), btnIcon);
		}
		else {
			btn = new JButton(gameSetting.getName());
		}
		btn.addActionListener(
			    new ActionListener() {
			        public void actionPerformed(ActionEvent e) {
			    		GameSelectionEvent se = new GameSelectionEvent(this, gameSetting);
			    		fireSelectionEvent(se);
			        }
			    }
		);
		btn.setFocusable(false);
		btn.setVerticalTextPosition(AbstractButton.BOTTOM);
		btn.setHorizontalTextPosition(AbstractButton.CENTER);
		
		return btn;
	}


	/**
	 * Generoidaan nappi, jolla päästään valikossa takaisin
	 */
	private Component generateBackButton(String path, String description) {
		ImageIcon btnIcon = createImageIcon(path, description);
		JButton btn = null;
		if(btnIcon!=null) {
			btn = new JButton(description, btnIcon);
		}
		else {
			btn = new JButton(description);
		}
		btn.addActionListener(
			    new ActionListener() {
			        public void actionPerformed(ActionEvent e) {
						GameSelectionEvent se = new GameSelectionEvent(this,null);
						fireSelectionEvent(se);
			        }
			    }
		);
		btn.setFocusable(false);
		btn.setVerticalTextPosition(AbstractButton.BOTTOM);
		btn.setHorizontalTextPosition(AbstractButton.CENTER);
		return btn;
	}

	/** Returns an ImageIcon, or null if the path was invalid. */
	protected ImageIcon createImageIcon(String path, String description) {
		MediaResource mr = MediaResource.getInstance();
		int width, height;
		BufferedImage img = null;
		if(!mr.containsKey(path))
		{
			mr.setImage(path);
			System.out.println("Ladataan " + path);
		}
		img = mr.get(path);
		if(img.getWidth()/this.iconWidth > img.getHeight()/this.iconHeight) {
			width = this.iconWidth;
			height = -1;
		}
		else {
			width = -1;
			height = this.iconHeight;
		}
		ImageIcon icon = null;
		String iconKey = path+width+height;
		if(!mr.containsIconKey(iconKey))
		{
			mr.setIcon(iconKey, new ImageIcon(img.getScaledInstance(width, height, 
	        		Image.SCALE_FAST), description));
			System.out.println("Ladataan " + iconKey);
		}
		icon = mr.getIcon(iconKey);
        return icon;
	}

	
	public void addSelectionListener(SelectionListener  listener) {
		this.listener = listener;
	}
	
	public void removeSelectionListener(SelectionListener listener) {
		if (this.listener == listener) {
			this.listener = null;
		}
	}
	
	private void fireSelectionEvent(EventObject se) {
		if (this.listener != null)
			this.listener.selectionEventOccurred(se);
	}

	@Override
	public void keyPressed(KeyEvent arg0) {
		// Kun painetaan control + n palataan valikossa takaisin
		if (arg0.isControlDown() && arg0.getKeyCode() == KeyEvent.VK_N) {
			GameSelectionEvent se = new GameSelectionEvent(this,null);
			this.fireSelectionEvent(se);
		}
	}

	@Override
	public void keyReleased(KeyEvent arg0) {
		// ei tarvetta.
	}

	@Override
	public void keyTyped(KeyEvent arg0) {
		// ei tarvetta.
		
	}
	
	protected void setUserSetting(ArrayList<GameSettings> gameList) {
		this.removeAll();
		int gameCount = gameList.size();

		Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
	    int gridColumns = (int)(Math.sqrt(gameCount)+1);
		this.setLayout(new BorderLayout());
		this.iconHeight = (int) (screenSize.height * 0.08f);
		this.iconWidth = (int) (screenSize.width * 0.08f);
	    JPanel controlButtonPanel = new JPanel();
	    this.add(controlButtonPanel, BorderLayout.PAGE_START);
	    controlButtonPanel.setLayout(new BorderLayout());
		controlButtonPanel.add(generateBackButton(BACKBUTTON_IMAGE, backButtonText), BorderLayout.LINE_START);

	    JPanel panel = new JPanel();
	    this.add(panel, BorderLayout.CENTER);
	    panel.setLayout(new GridLayout(gridColumns, gridColumns));
		this.iconHeight = (int) (screenSize.height * 0.8f / gridColumns);
		this.iconWidth = (int) (screenSize.width * 0.8f / gridColumns);
		
		for(int i=0;i<gameCount;i++) {
			panel.add(generateSelectionButton(gameList.get(i)));
		}
	}


	public void setUsers(ArrayList<UserSetting> userList, @SuppressWarnings("rawtypes") Class settingsClass) {
		ArrayList<GameSettings> gameList = new ArrayList<GameSettings>();
		Iterator<UserSetting> iterator = userList.iterator();
		while(iterator.hasNext()) {
			UserSetting user = iterator.next();
			if(user.getGameFileList()!=null) {
				Iterator<String> gameFileIterator = user.getGameFileList().iterator();
				while(gameFileIterator.hasNext()) {
					String gameFile = gameFileIterator.next();
					//load game file
					GameSettings gameSetting = null;
					try {
						gameSetting = (GameSettings) SettingsReader.getInstance().readSettings(
								gameFile, settingsClass);
					} catch (Exception e) {
						e.printStackTrace();
					}
					if(gameSetting!=null)
					{
						gameSetting.setSetupFile(gameFile);
						gameList.add(gameSetting);
					}
				}
			}
		}
		
		setUserSetting(gameList);
		
		setFont(getFont());
		setForeground(getForeground());
	}
}
